package com.quectel.cms.controller.partybuildingactivity;


import com.quectel.business.common.partybuilding.PartyPersonBusiness;
import com.quectel.business.common.partybuilding.PartyPersonMsgBusiness;
import com.quectel.business.common.util.sys.SysCodeUtils;
import com.quectel.cms.controller.BaseController;
import com.quectel.constant.PushConstants;
import com.quectel.constant.core.mobileuser.MobileUserMsgConstants;
import com.quectel.constant.core.partybuilding.PartyBuildingConstants;
import com.quectel.constant.core.partybuilding.PartyBuildingMeetingConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.util.aspect.log.annotation.Log;
import com.quectel.constant.global.annotation.RequirePermissions;
import com.quectel.constant.sys.SysCodeKeyConstants;
import com.quectel.core.module.mobileuser.dto.MobileUserDto;
import com.quectel.core.module.mobileuser.service.MobileUserService;
import com.quectel.core.module.partybuilding.dto.PartyPersonDto;
import com.quectel.core.module.partybuilding.service.PartyPersonService;
import com.quectel.core.module.partybuildingactivity.dto.PartyBuildingActivityDto;
import com.quectel.core.module.partybuildingactivity.dto.PartyBuildingActivityPersonJoinBindingDto;
import com.quectel.core.module.partybuildingactivity.service.PartyBuildingActivityPersonJoinBindingService;
import com.quectel.core.module.partybuildingactivity.service.PartyBuildingActivityService;
import com.quectel.util.common.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @author bob
 * @email bob.yu@quectel.com
 * @date 2023/05/24 11:38
 */
@RestController
@RequestMapping("partyBuildingActivity")
@Tag(name = "PartyBuildingActivityController", description = "党建活动相关api")
public class PartyBuildingActivityController extends BaseController {

    @DubboReference
    private PartyBuildingActivityService partyBuildingActivityService;
    @DubboReference
    private PartyPersonService partyPersonService;
    @DubboReference
    private PartyBuildingActivityPersonJoinBindingService activityPersonJoinBindingService;
    @DubboReference
    private MobileUserService mobileUserService;

    @Autowired
    private PartyPersonBusiness partyPersonBusiness;
    @Autowired
    private PartyPersonMsgBusiness partyPersonMsgBusiness;

    /**
     * 编辑会议纪要
     *
     * @param partyBuildingActivityDto
     * @return
     */
    @PostMapping("updateSummary")
    public Response<Object> saveSummary(@RequestBody @Validated PartyBuildingActivityDto partyBuildingActivityDto) {
        partyBuildingActivityService.updateById(partyBuildingActivityDto);
        return Response.ok();
    }

    /**
     * 查看会议纪要
     *
     * @param id
     * @return
     */
    @GetMapping("summaryInfo/{id}")
    public Response<PartyBuildingActivityDto> summaryInfo(@PathVariable("id") Long id) {
        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (partyBuildingActivityService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        PartyBuildingActivityDto partyBuildingActivityDto = partyBuildingActivityService.selectById(id);
        return Response.<PartyBuildingActivityDto>ok().wrap(partyBuildingActivityDto);
    }

    @PostMapping("release")
    @RequirePermissions(values = "partyBuildingActivity:cancel")
    @Operation(summary = "发布操作")
    public Response<Object> release(@RequestBody Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (partyBuildingActivityService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        PartyBuildingActivityDto updately = new PartyBuildingActivityDto();
        updately.setId(id);
        updately.setStatus(SystemConstants.YES);
        updately.setEditTime(new Date());
        partyBuildingActivityService.updateById(updately);

        PartyBuildingActivityDto dbValue = partyBuildingActivityService.selectById(id);
        List<PartyPersonDto> partyPersonList = getBindPersonList(dbValue);
        dbValue.setPartyPersonList(partyPersonList);

        List<PartyPersonDto> bindPersonList = getBindPersonList(dbValue);
        dbValue.setPartyPersonList(bindPersonList);
        // 是否需要报名提醒
        if (SystemConstants.YES.equals(dbValue.getStatus())
                && PartyBuildingMeetingConstants.RemindType.INSTANT_REMINDER.getType().equals(dbValue.getJoinRemindType())) {
            pushReminderMessage(dbValue,
                    MobileUserMsgConstants.SourceType.PARTY_ACTIVITY_JOIN_REMIND,
                    dbValue.getJoinStartTime(),
                    dbValue.getJoinEndTime());
        }

        // 是否需要活动开始前提醒
        if (SystemConstants.YES.equals(dbValue.getStatus())
                && PartyBuildingMeetingConstants.RemindType.INSTANT_REMINDER.getType().equals(dbValue.getActivityRemindType())) {
            pushReminderMessage(dbValue,
                    MobileUserMsgConstants.SourceType.PARTY_ACTIVITY_BEGIN_REMIND,
                    dbValue.getActivityStartTime(),
                    dbValue.getActivityEndTime());
        }

        return Response.ok();
    }

    @PostMapping("cancel")
    @RequirePermissions(values = "partyBuildingActivity:cancel")
    @Operation(summary = "取消操作")
    public Response<Object> cancel(@RequestBody Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (partyBuildingActivityService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        PartyBuildingActivityDto updately = new PartyBuildingActivityDto();
        updately.setId(id);
        updately.setStatus(PartyBuildingMeetingConstants.MeetingStatus.CANCEL.getStatus());
        updately.setEditTime(new Date());
        partyBuildingActivityService.updateById(updately);

        return Response.ok();
    }

    @GetMapping("exportExcel")
    @RequirePermissions(values = "partyBuildingActivity:export")
    @Operation(summary = "导出主题活动列表")
    @Log(express = "导出主题活动列表")
    public void exportExcel(@RequestParam Map<String, Object> params, HttpServletResponse hresp) {
        Request request = Request.configParamsNotPage(params);

        super.fillAuthorityData(params);

        List<PartyBuildingActivityDto> result = new ArrayList<>();
        int pageNo = 0;
        params.put("limit", 1000);
        while (true) {
            params.put("offset", pageNo++ * 1000);
            List<PartyBuildingActivityDto> list = partyBuildingActivityService.queryList(request.getParams());
            if (org.apache.commons.collections4.CollectionUtils.isEmpty(list)) {
                break;
            }
            result.addAll(list);
            if (list.size() < 1000) {
                break;
            }
        }
        String[] headers = new String[]{"所属党组织", "活动主题", "活动类型", "活动地点", "活动开始时间", "活动结束时间", "报名人数", "参加人数", "创建时间"};
        List<String[]> dataList = new ArrayList<>();
        for (PartyBuildingActivityDto data : result) {
            String[] item = new String[headers.length];
            item[0] = data.getPartyName();
            item[1] = data.getSubject();
            item[2] = SysCodeUtils.easyToGetName(SysCodeKeyConstants.PARTY_BUILDING_ACTIVITY_TYPE, data.getType() + "");
            item[3] = data.getAddress();
            item[4] = DateUtils.format(data.getActivityStartTime(), DateUtils.FormatType.COMMON);
            item[5] = DateUtils.format(data.getActivityEndTime(), DateUtils.FormatType.COMMON);
            item[6] = data.getJoinCount() + "/" + data.getTotalJoinCount();
            item[7] = data.getSignCount() + "/" + data.getTotalJoinCount();
            item[8] = DateUtils.format(data.getCreateTime(), DateUtils.FormatType.COMMON);
            dataList.add(item);
        }
        POIUtils.exportExcel(hresp, "主题活动", headers, dataList, "主题活动列表");
    }

    /**
     * 分页查询
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("list")
    @RequirePermissions(values = "partyBuildingActivity:list")
    @Operation(summary = "分页获取党建活动列表")
    public Response<Page<PartyBuildingActivityDto>> list(
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize
    ) {
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        super.fillAuthorityData(request.getParams());
        int total = partyBuildingActivityService.queryTotal(request.getParams());

        List<PartyBuildingActivityDto> list = null;
        if (total > 0) {
            list = partyBuildingActivityService.queryList(request.getParams());
        } else {
            list = new ArrayList<>();
        }

        Page<PartyBuildingActivityDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<PartyBuildingActivityDto>>ok().wrap(page);
    }

    /**
     * 编辑查询反显
     *
     * @param id
     * @return
     */
    @GetMapping("infoForEdit/{id}")
    @RequirePermissions(values = "partyBuildingActivity:edit")
    @Operation(summary = "在编辑时根据id查询党建活动详情")
    public Response<PartyBuildingActivityDto> infoForEdit(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (partyBuildingActivityService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        PartyBuildingActivityDto partyBuildingActivityDto = partyBuildingActivityService.selectById(id);
        List<PartyPersonDto> partyPersonDtoList = new ArrayList<>();
        List<PartyBuildingActivityPersonJoinBindingDto> bindingDtos = activityPersonJoinBindingService.selectList(id);
        if (CollectionUtils.isNotEmpty(bindingDtos)) {
            for (PartyBuildingActivityPersonJoinBindingDto bindingDto : bindingDtos) {
                PartyPersonDto personDto = partyPersonService.selectCacheById(bindingDto.getPartyPersonId());
                if (personDto != null) {
                    partyPersonDtoList.add(personDto);
                }
            }
        }
        partyBuildingActivityDto.setPartyPersonList(partyPersonDtoList);

        return Response.<PartyBuildingActivityDto>ok().wrap(partyBuildingActivityDto);
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    @GetMapping("info/{id}")
    @RequirePermissions(values = "partyBuildingActivity:info")
    @Operation(summary = "根据id查询党建活动的详情")
    public Response<PartyBuildingActivityDto> info(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (partyBuildingActivityService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        PartyBuildingActivityDto partyBuildingActivityDto = partyBuildingActivityService.selectById(id);

        return Response.<PartyBuildingActivityDto>ok().wrap(partyBuildingActivityDto);
    }

    /**
     * 保存
     *
     * @param partyBuildingActivityDto
     * @return
     */
    @PostMapping("save")
    @RequirePermissions(values = "partyBuildingActivity:edit")
    @Operation(summary = "新增党建活动")
    public Response<Object> save(@RequestBody @Validated PartyBuildingActivityDto partyBuildingActivityDto) {

        Map<String, Object> params = new HashMap<>();
        //填充基础数据
        fillSaveCommonData(partyBuildingActivityDto);

        // 不推送或者即时推送 签到
        if (PartyBuildingMeetingConstants.RemindType.INSTANT_REMINDER.getType().equals(partyBuildingActivityDto.getJoinRemindType())
                || PartyBuildingMeetingConstants.RemindType.NO_NEED.getType().equals(partyBuildingActivityDto.getJoinRemindType())
        ){
            partyBuildingActivityDto.setIsPushJoin(SystemConstants.YES);
        }else {
            partyBuildingActivityDto.setIsPushJoin(SystemConstants.NO);
        }

        // 不推送或者即时推送 报名
        if (PartyBuildingMeetingConstants.RemindType.INSTANT_REMINDER.getType().equals(partyBuildingActivityDto.getActivityRemindType())
                || PartyBuildingMeetingConstants.RemindType.NO_NEED.getType().equals(partyBuildingActivityDto.getActivityRemindType())
        ){
            partyBuildingActivityDto.setIsPushActivity(SystemConstants.YES);
        }else {
            partyBuildingActivityDto.setIsPushActivity(SystemConstants.NO);
        }

        Long activityId = null;

        if (CollectionUtils.isEmpty(partyBuildingActivityDto.getPartyPersonList())){
            return Response.error("请选择参会人员");
        }
        activityId = partyBuildingActivityService.saveOrUpdate(partyBuildingActivityDto);

        PartyBuildingActivityDto dbValue = partyBuildingActivityService.selectCacheById(activityId);
        dbValue.setPartyPersonList(partyBuildingActivityDto.getPartyPersonList());
        List<PartyPersonDto> bindPersonList = getBindPersonList(dbValue);
        dbValue.setPartyPersonList(bindPersonList);

        // 是否需要报名提醒
        if (SystemConstants.YES.equals(partyBuildingActivityDto.getStatus())
                && PartyBuildingMeetingConstants.RemindType.INSTANT_REMINDER.getType().equals(partyBuildingActivityDto.getJoinRemindType())) {
            pushReminderMessage(dbValue,
                    MobileUserMsgConstants.SourceType.PARTY_ACTIVITY_JOIN_REMIND,
                    partyBuildingActivityDto.getJoinStartTime(),
                    partyBuildingActivityDto.getJoinEndTime());
        }

        // 是否需要活动开始前提醒
        if (SystemConstants.YES.equals(partyBuildingActivityDto.getStatus())
                && PartyBuildingMeetingConstants.RemindType.INSTANT_REMINDER.getType().equals(partyBuildingActivityDto.getActivityRemindType())) {
            pushReminderMessage(dbValue,
                    MobileUserMsgConstants.SourceType.PARTY_ACTIVITY_BEGIN_REMIND,
                    dbValue.getActivityStartTime(),
                    dbValue.getActivityEndTime());
        }

        return Response.ok();
    }


    /**
     * 修改
     *
     * @param partyBuildingActivityDto
     * @return
     */
    @PostMapping("update")
    @RequirePermissions(values = "partyBuildingActivity:edit")
    @Operation(summary = "根据id修改党建活动")
    public Response<Object> update(@RequestBody @Validated PartyBuildingActivityDto partyBuildingActivityDto) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(partyBuildingActivityDto.getId()));
        if (partyBuildingActivityService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        //填充基础数据
        fillEditCommonData(partyBuildingActivityDto);

        params.remove(SystemConstants.ENTITY_ID_FLAG);

        // 不推送或者即时推送 签到
        if (PartyBuildingMeetingConstants.RemindType.INSTANT_REMINDER.getType().equals(partyBuildingActivityDto.getJoinRemindType())
                ||
                PartyBuildingMeetingConstants.RemindType.NO_NEED.getType().equals(partyBuildingActivityDto.getJoinRemindType())
        ){
            partyBuildingActivityDto.setIsPushJoin(SystemConstants.YES);
        }else {
            partyBuildingActivityDto.setIsPushJoin(SystemConstants.NO);
        }

        // 不推送或者即时推送 报名
        if (PartyBuildingMeetingConstants.RemindType.INSTANT_REMINDER.getType().equals(partyBuildingActivityDto.getActivityRemindType())
                || PartyBuildingMeetingConstants.RemindType.NO_NEED.getType().equals(partyBuildingActivityDto.getActivityRemindType())
        ){
            partyBuildingActivityDto.setIsPushActivity(SystemConstants.YES);
        }else {
            partyBuildingActivityDto.setIsPushActivity(SystemConstants.NO);
        }

        if (CollectionUtils.isEmpty(partyBuildingActivityDto.getPartyPersonList())){
            return Response.error("请选择参会人员");
        }
        partyBuildingActivityService.saveOrUpdate(partyBuildingActivityDto);

        return Response.ok();
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @PostMapping("delete")
    @RequirePermissions(values = "partyBuildingActivity:delete")
    @Operation(summary = "根据多条记录id批量删除党建活动")
    public Response<Object> delete(@RequestBody Long[] ids) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);

        for (Long id : ids) {

            params.remove(SystemConstants.ENTITY_ID_FLAG);
            params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));

            if (partyBuildingActivityService.queryTotal(params) <= 0) {
                return Response.error(SystemConstants.ILLEGAL_MSG);
            }
        }

        partyBuildingActivityService.deleteBatch(ids);

        return Response.ok();
    }

    private void pushReminderMessage(PartyBuildingActivityDto activityDto, MobileUserMsgConstants.SourceType sourceType, Date startTime, Date endTime) {
        List<MobileUserDto> sendUserList = new ArrayList<>();
        List<PartyPersonDto> partyPersonList = activityDto.getPartyPersonList();
        for (PartyPersonDto partyPerson : partyPersonList) {
            MobileUserDto mobileUserDto = mobileUserService.selectByMobile(partyPerson.getMobile());
            if (mobileUserDto != null) {
                sendUserList.add(mobileUserDto);
            }
        }
        if (CollectionUtils.isNotEmpty(sendUserList)) {
            partyPersonMsgBusiness.pushMsg(
                    activityDto.getTenantId(),
                    sendUserList,
                    sourceType,
                    activityDto.getId(),
                    String.format(PartyBuildingConstants.PUSH_MSG_ACTIVITY_TITLE,
                            sourceType.getDefaultTitle()),
                    String.format(PartyBuildingConstants.PUSH_MSG_TEMPLATE,
                            activityDto.getSubject(),
                            DateUtils.format(startTime, DateUtils.FormatType.COMMON),
                            DateUtils.format(endTime, DateUtils.FormatType.COMMON)
                    ),
                    true,
                    new PushConstants.PushType[]{PushConstants.PushType.WECHAT_OFFICIAL}
            );
        }
    }

    /**
     * 获取绑定的人员列表
     * @param activityDto
     * @return
     */
    private List<PartyPersonDto> getBindPersonList(PartyBuildingActivityDto activityDto){
        List<PartyPersonDto> partyPersonDtoList = new ArrayList<>();
        List<PartyBuildingActivityPersonJoinBindingDto> bindList
                = activityPersonJoinBindingService.selectList(activityDto.getId());
        if (CollectionUtils.isEmpty(bindList)){
            return partyPersonDtoList;
        }

        for (PartyBuildingActivityPersonJoinBindingDto bindingDto : bindList) {
            PartyPersonDto partyPersonDto = partyPersonService.selectCacheById(bindingDto.getPartyPersonId());
            if (partyPersonDto!=null){
                partyPersonDtoList.add(partyPersonDto);
            }
        }

        return partyPersonDtoList;

    }

}
